from load_planer.models import ShippingContainer,Task
from .utils.db import get_model_permissions
from django.contrib.auth.models import Permission
from enum import unique
import re
from typing import AbstractSet
from django.db import models
from django.contrib.auth.models import Permission, PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.utils.functional import empty
# Create your models here.


class Tenant(models.Model):
    schema_name = models.CharField(
        max_length=75,
        unique=True,
        help_text='租户的schema名'
    )

    organization = models.TextField(
        null=True,
        default=None,
        help_text='租户的企业名'
    )
    created = models.DateTimeField(auto_now_add=True, help_text='数据创建时间戳')


class RoleManager(models.Manager):

    def get_or_create(self, name, tenant, permissions):
        instance, created = super().get_or_create(
            name=name, tenant=tenant
        )
        if not created:
            return instance, created

        # 将权限赋予给角色
        if permissions:
            instance.permissions.set(permissions)

        return instance, created

    def create_admin_role(self, tenant):
        # 获取该角色的所有权限
        permissions = Permission.objects.all()
        # 获取/创建admin角色
        instance, created = self.get_or_create(
            name='admin',
            tenant=tenant,
            permissions=permissions
        )

        return instance

    def create_basic_role(self, tenant):
        """
        普通角色拥有的权限:

        - 查看 用户/集装箱运柜
        - 更新 用户
        - 查看/创建/更新/删除 任务
        """
        permissions = get_model_permissions(
            models=[User, ShippingContainer],
            permission_type='read'
        )+get_model_permissions(
            models=[User],
            permission_type='change'
        )+get_model_permissions(
            models=[Task],
            permission_type='all'
        )

        # TODO:获取任务相关的权限
        instance, created = self.get_or_create(
            name='basic',
            tenant=tenant,
            permissions=permissions
        )

        return instance


class Role(models.Model):
    name = models.CharField(
        max_length=150,
        help_text='角色名称'
    )
    tenant = models.ForeignKey(
        Tenant,
        related_name='roles',
        help_text='该角色所属的租户',
        on_delete=models.SET_NULL,
        null=True
    )
    permissions = models.ManyToManyField(
        Permission,
        help_text="该用户拥有的权限",
        blank=True
    )
    created = models.DateTimeField(auto_now_add=True, help_text='数据创建时间')
    objects = RoleManager()


class UserManager(BaseUserManager):

    def create(self, roles=None, **user_attrs):
        username = User.get_default_username(user_attrs['email'])
        instance = self.model(username=username, **user_attrs)
        instance.set_password(user_attrs['password'])
        instance.save()

        if roles:
            instance.roles.set(roles)
        return instance


class User(AbstractBaseUser, PermissionsMixin):
    objects = UserManager()
    USERNAME_FIELD = 'username'

    email = models.EmailField()
    username = models.TextField(
        unique=True,
    )

    first_name = models.CharField(max_length=100, default='', help_text='姓')
    last_name = models.CharField(max_length=100, default='', help_text='名')
    roles = models.ManyToManyField(
        Role,
        blank=True,
        help_text='该用户的角色',
        related_name='user_set',
        related_query_name='user'
    )
    tenant = models.ForeignKey(
        Tenant,
        related_name='users',
        help_text='该用户所属租户',
        on_delete=models.SET_NULL,
        null=True
    )
    created = models.DateTimeField(auto_now_add=True, help_text='数据创建时间')

    @staticmethod
    def get_default_schema(email: str):
        import hashlib
        if not email:
            return None
        email = email.lower().strip()
        HASH_LEN = 8

        email_hash = hashlib.blake2b(
            bytes(email, 'ascii'),
            digest_size=HASH_LEN
        ).hexdigest()
        return f'zmm_{email_hash}'

    @staticmethod
    def get_default_username(email: str):
        if not email:
            return None
        schema_name = User.get_default_schema(email)
        return f'{email}_{schema_name}'
